home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
335_03
/
as8048.y
< prev
next >
Wrap
Text File
|
1990-12-02
|
40KB
|
1,757 lines
%{
/*
HEADER: ;
TITLE: Frankenstein Cross Assemblers;
VERSION: 2.0;
DESCRIPTION: " Reconfigurable Cross-assembler producing Intel (TM)
Hex format object records. ";
KEYWORDS: cross-assemblers, 1805, 2650, 6301, 6502, 6805, 6809,
6811, tms7000, 8048, 8051, 8096, z8, z80;
SYSTEM: UNIX, MS-Dos ;
FILENAME: as8048.y;
WARNINGS: "This software is in the public domain.
Any prior copyright claims are relinquished.
This software is distributed with no warranty whatever.
The author takes no responsibility for the consequences
of its use.
Yacc (or Bison) required to compile." ;
SEE-ALSO: as8048.doc,frasmain.c;
AUTHORS: Mark Zenier;
COMPILERS: Microport Sys V/AT, ATT Yacc, Turbo C V1.5, Bison (CUG disk 285)
(previous versions Xenix, Unisoft 68000 Version 7, Sun 3);
*/
/* 8048 et al instruction generation file */
/* November 17, 1990 */
/*
description frame work parser description for framework cross
assemblers
history February 2, 1988
September 11, 1990 - merge table definition
September 12, 1990 - short file names
September 14, 1990 - short variable names
September 17, 1990 - use yylex as external
*/
#include <stdio.h>
#include "frasmdat.h"
#include "fragcon.h"
#define yylex lexintercept
/* 0000.0000.0000.xxxx interrupt selections */
#define ISELMASK 0xf
#define ISELI 0x1
#define ISELTCNTI 0x2
#define ISELDMA 0x4
#define ISELFLAGS 0x8
/* 0000.0000.0000.xxxx accum-flag selections */
#define AFSELMASK 0xf
#define AFSELA 0x1
#define AFSELC 0x2
#define AFSELF0 0x4
#define AFSELF1 0x8
/* 0000.0000.xxxx.0000 low port selections */
#define PSELMASK 0xf0
#define PSELBUS 0x10
#define PSELP1 0x20
#define PSELP2 0x40
#define PSELDBB 0x80
/* 0000.00xx.xxxx.0000 misc register selections */
#define MSELMASK 0x3f0
#define MSELPSW 0x10
#define MSELT 0x20
#define MSELCNT 0x40
#define MSELTCNT 0x80
#define MSELCLK 0x100
#define MSELSTS 0x200
/* 0000.xx00.0000.0000 ram size */
#define RAMSIZEMASK 0xc00
#define RAMSIZE64 0x400
#define RAMSIZE128 0x800
#define RAMSIZE256 0xc00
/* xxx0.0000.0000.0000 instruction set variations */
#define INSTIDL 0x8000
#define INSTNOT41 0x4000
#define INST41 0x2000
#define CPU8048 INSTNOT41|RAMSIZE64
#define CPU8049 INSTNOT41|RAMSIZE128
#define CPU8050 INSTNOT41|RAMSIZE256
#define CPU80C48 INSTNOT41|INSTIDL|RAMSIZE64
#define CPU80C49 INSTNOT41|INSTIDL|RAMSIZE128
#define CPU80C50 INSTNOT41|INSTIDL|RAMSIZE256
#define CPU8041 INST41|RAMSIZE64
#define CPU8042 INST41|RAMSIZE128
#define ST_AF 0x1
#define ST_REG 0x2
#define ST_EXPR 0x4
#define ST_AR 0x8
#define ST_AINDIRR 0x10
#define ST_AIMMED 0x20
#define ST_INDIRA 0x40
#define ST_INDIRR 0x80
#define ST_REGEXP 0x100
#define ST_PA2 0x200
#define ST_PA4 0x400
#define ST_P2A 0x800
#define ST_P4A 0x1000
#define ST_P2IMMED 0x2000
#define ST_INH 0x1
#define ST_INT 0x2
#define ST_RSELC 0x4
#define ST_MSELC 0x8
#define ST_MREG 0x10
#define ST_MAR 0x1
#define ST_MAINDIRA 0x2
#define ST_MAINDIRR 0x4
#define ST_MAIMMED 0x8
#define ST_MAMR 0x10
#define ST_MMRA 0x20
#define ST_MRA 0x40
#define ST_MRIMMED 0x80
#define ST_MINDIRRA 0x100
#define ST_MINDIRRIM 0x200
static char genbdef[] = "[1=];";
static char genwdef[] = "[1=]y"; /* x for normal, y for byte rev */
char ignosyn[] = "[Xinvalid syntax for instruction";
char ignosel[] = "[Xinvalid operands/illegal instruction for cpu";
int cpuselect = CPU80C50;
long labelloc;
static int satsub;
int ifstkpt = 0;
int fraifskip = FALSE;
struct symel * endsymbol = SYMNULL;
%}
%union {
int intv;
long longv;
char *strng;
struct symel *symb;
}
%token <intv> RSELC
%token <intv> MSELC
%token <intv> INT
%token <intv> AF
%token <intv> REG
%token <intv> P02
%token <intv> P47
%token <intv> MREG
%token <intv> KOC_BDEF
%token <intv> KOC_ELSE
%token <intv> KOC_END
%token <intv> KOC_ENDI
%token <intv> KOC_EQU
%token <intv> KOC_IF
%token <intv> KOC_INCLUDE
%token <intv> KOC_ORG
%token <intv> KOC_RESM
%token <intv> KOC_SDEF
%token <intv> KOC_SET
%token <intv> KOC_WDEF
%token <intv> KOC_CHSET
%token <intv> KOC_CHDEF
%token <intv> KOC_CHUSE
%token <intv> KOC_CPU
%token <intv> KOC_REG
%token <intv> KOC_opcode
%token <intv> KOC_misc
%token <intv> KOC_mov
%token <longv> CONSTANT
%token EOL
%token KEOP_AND
%token KEOP_DEFINED
%token KEOP_EQ
%token KEOP_GE
%token KEOP_GT
%token KEOP_HIGH
%token KEOP_LE
%token KEOP_LOW
%token KEOP_LT
%token KEOP_MOD
%token KEOP_MUN
%token KEOP_NE
%token KEOP_NOT
%token KEOP_OR
%token KEOP_SHL
%token KEOP_SHR
%token KEOP_XOR
%token KEOP_locctr
%token <symb> LABEL
%token <strng> STRING
%token <symb> SYMBOL
%token KTK_invalid
%right KEOP_HIGH KEOP_LOW
%left KEOP_OR KEOP_XOR
%left KEOP_AND
%right KEOP_NOT
%nonassoc KEOP_GT KEOP_GE KEOP_LE KEOP_LT KEOP_NE KEOP_EQ
%left '+' '-'
%left '*' '/' KEOP_MOD KEOP_SHL KEOP_SHR
%right KEOP_MUN
%type <intv> expr exprlist stringlist
%start file
%%
file : file allline
| allline
;
allline : line EOL
{
clrexpr();
}
| EOL
| error EOL
{
clrexpr();
yyerrok;
}
;
line : LABEL KOC_END
{
endsymbol = $1;
nextreadact = Nra_end;
}
| KOC_END
{
nextreadact = Nra_end;
}
| KOC_INCLUDE STRING
{
if(nextfstk >= FILESTKDPTH)
{
fraerror("include file nesting limit exceeded");
}
else
{
infilestk[nextfstk].fnm = savestring($2,strlen($2));
if( (infilestk[nextfstk].fpt = fopen($2,"r"))
==(FILE *)NULL )
{
fraerror("cannot open include file");
}
else
{
nextreadact = Nra_new;
}
}
}
| LABEL KOC_EQU expr
{
if($1 -> seg == SSG_UNDEF)
{
pevalexpr(0, $3);
if(evalr[0].seg == SSG_ABS)
{
$1 -> seg = SSG_EQU;
$1 -> value = evalr[0].value;
prtequvalue("C: 0x%lx\n",
evalr[0].value);
}
else
{
fraerror(
"noncomputable expression for EQU");
}
}
else
{
fraerror(
"cannot change symbol value with EQU");
}
}
| LABEL KOC_SET expr
{
if($1 -> seg == SSG_UNDEF
|| $1 -> seg == SSG_SET)
{
pevalexpr(0, $3);
if(evalr[0].seg == SSG_ABS)
{
$1 -> seg = SSG_SET;
$1 -> value = evalr[0].value;
prtequvalue("C: 0x%lx\n",
evalr[0].value);
}
else
{
fraerror(
"noncomputable expression for SET");
}
}
else
{
fraerror(
"cannot change symbol value with SET");
}
}
| KOC_IF expr
{
if((++ifstkpt) < IFSTKDEPTH)
{
pevalexpr(0, $2);
if(evalr[0].seg == SSG_ABS)
{
if(evalr[0].value != 0)
{
elseifstk[ifstkpt] = If_Skip;
endifstk[ifstkpt] = If_Active;
}
else
{
fraifskip = TRUE;
elseifstk[ifstkpt] = If_Active;
endifstk[ifstkpt] = If_Active;
}
}
else
{
fraifskip = TRUE;
elseifstk[ifstkpt] = If_Active;
endifstk[ifstkpt] = If_Active;
}
}
else
{
fraerror("IF stack overflow");
}
}
| KOC_IF
{
if(fraifskip)
{
if((++ifstkpt) < IFSTKDEPTH)
{
elseifstk[ifstkpt] = If_Skip;
endifstk[ifstkpt] = If_Skip;
}
else
{
fraerror("IF stack overflow");
}
}
else
{
yyerror("syntax error");
YYERROR;
}
}
| KOC_ELSE
{
switch(elseifstk[ifstkpt])
{
case If_Active:
fraifskip = FALSE;
break;
case If_Skip:
fraifskip = TRUE;
break;
case If_Err:
fraerror("ELSE with no matching if");
break;
}
}
| KOC_ENDI
{
switch(endifstk[ifstkpt])
{
case If_Active:
fraifskip = FALSE;
ifstkpt--;
break;
case If_Skip:
fraifskip = TRUE;
ifstkpt--;
break;
case If_Err:
fraerror("ENDI with no matching if");
break;
}
}
| LABEL KOC_ORG expr
{
pevalexpr(0, $3);
if(evalr[0